﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using IPC.Communication.Framework.BasicFramework;

namespace IPC.Communication.Framework.Core
{
    public class HslHelper
    {
        public static int ExtractParameter(ref string address, string paraName, int defaultValue)
        {
            OperateResult<int> operateResult = HslHelper.ExtractParameter(ref address, paraName);
            return operateResult.IsSuccess ? operateResult.Content : defaultValue;
        }

        public static OperateResult<int> ExtractParameter(ref string address, string paraName)
        {
            OperateResult<int> result;
            try
            {
                Match match = Regex.Match(address, paraName + "=[0-9A-Fa-fx]+;");
                bool flag = !match.Success;
                if (flag)
                {
                    result = new OperateResult<int>(string.Concat(new string[]
					{
						"Address [",
						address,
						"] can't find [",
						paraName,
						"] Parameters. for example : ",
						paraName,
						"=1;100"
					}));
                }
                else
                {
                    string text = match.Value.Substring(paraName.Length + 1, match.Value.Length - paraName.Length - 2);
                    int value = text.StartsWith("0x") ? Convert.ToInt32(text.Substring(2), 16) : (text.StartsWith("0") ? Convert.ToInt32(text, 8) : Convert.ToInt32(text));
                    address = address.Replace(match.Value, "");
                    result = OperateResult.CreateSuccessResult<int>(value);
                }
            }
            catch (Exception ex)
            {
                result = new OperateResult<int>(string.Concat(new string[]
				{
					"Address [",
					address,
					"] Get [",
					paraName,
					"] Parameters failed: ",
					ex.Message
				}));
            }
            return result;
        }

        public static int ExtractStartIndex(ref string address)
        {
            int result;
            try
            {
                Match match = Regex.Match(address, "\\[[0-9]+\\]$");
                bool flag = !match.Success;
                if (flag)
                {
                    result = -1;
                }
                else
                {
                    string value = match.Value.Substring(1, match.Value.Length - 2);
                    int num = Convert.ToInt32(value);
                    address = address.Remove(address.Length - match.Value.Length);
                    result = num;
                }
            }
            catch
            {
                result = -1;
            }
            return result;
        }

        public static IByteTransform ExtractTransformParameter(ref string address, IByteTransform defaultTransform)
        {
            IByteTransform result;
            result = defaultTransform;


            try
            {
                string text = "format";
                Match match = Regex.Match(address, text + "=(ABCD|BADC|DCBA|CDAB);", RegexOptions.IgnoreCase);
                bool flag2 = !match.Success;
                if (flag2)
                {
                    result = defaultTransform;
                }
                else
                {
                    string text2 = match.Value.Substring(text.Length + 1, match.Value.Length - text.Length - 2);
                    DataFormat dataFormat = defaultTransform.DataFormat;
                    string text3 = text2.ToUpper();
                    string a = text3;
                    if (!(a == "ABCD"))
                    {
                        if (!(a == "BADC"))
                        {
                            if (!(a == "DCBA"))
                            {
                                if (a == "CDAB")
                                {
                                    dataFormat = DataFormat.CDAB;
                                }
                            }
                            else
                            {
                                dataFormat = DataFormat.DCBA;
                            }
                        }
                        else
                        {
                            dataFormat = DataFormat.BADC;
                        }
                    }
                    else
                    {
                        dataFormat = DataFormat.ABCD;
                    }
                    address = address.Replace(match.Value, "");
                    bool flag3 = dataFormat != defaultTransform.DataFormat;
                    if (flag3)
                    {
                        result = defaultTransform.CreateByDateFormat(dataFormat);
                    }
                    else
                    {
                        result = defaultTransform;
                    }
                }
            }
            catch
            {
                throw;
            }

            return result;
        }

        public static OperateResult<int[], int[]> SplitReadLength(int address, ushort length, ushort segment)
        {
            int[] array = SoftBasic.SplitIntegerToArray((int)length, (int)segment);
            int[] array2 = new int[array.Length];
            for (int i = 0; i < array2.Length; i++)
            {
                bool flag = i == 0;
                if (flag)
                {
                    array2[i] = address;
                }
                else
                {
                    array2[i] = array2[i - 1] + array[i - 1];
                }
            }
            return OperateResult.CreateSuccessResult<int[], int[]>(array2, array);
        }

        public static OperateResult<int[], List<T[]>> SplitWriteData<T>(int address, T[] value, ushort segment, int addressLength)
        {
            List<T[]> list = SoftBasic.ArraySplitByLength<T>(value, (int)segment * addressLength);
            int[] array = new int[list.Count];
            for (int i = 0; i < array.Length; i++)
            {
                bool flag = i == 0;
                if (flag)
                {
                    array[i] = address;
                }
                else
                {
                    array[i] = array[i - 1] + list[i - 1].Length / addressLength;
                }
            }
            return OperateResult.CreateSuccessResult<int[], List<T[]>>(array, list);
        }

        public static int GetBitIndexInformation(ref string address)
        {
            int result = 0;
            int num = address.LastIndexOf('.');
            bool flag = num > 0 && num < address.Length - 1;
            if (flag)
            {
                string text = address.Substring(num + 1);
                bool flag2 = text.Contains("A") || text.Contains("B") || text.Contains("C") || text.Contains("D") || text.Contains("E") || text.Contains("F");
                if (flag2)
                {
                    result = Convert.ToInt32(text, 16);
                }
                else
                {
                    result = Convert.ToInt32(text);
                }
                address = address.Substring(0, num);
            }
            return result;
        }

        public static string GetIpAddressFromInput(string value)
        {
            bool flag = !string.IsNullOrEmpty(value);
            string result;
            if (flag)
            {
                bool flag2 = Regex.IsMatch(value, "^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$");
                if (flag2)
                {
                    IPAddress iPAddress;
                    bool flag3 = !IPAddress.TryParse(value, out iPAddress);
                    if (flag3)
                    {
                        throw new Exception(StringResources.Language.IpAddressError);
                    }
                    result = value;
                    return result;
                }
                else
                {
                    IPHostEntry hostEntry = Dns.GetHostEntry(value);
                    IPAddress[] addressList = hostEntry.AddressList;
                    bool flag4 = addressList.Length != 0;
                    if (flag4)
                    {
                        result = addressList[0].ToString();
                        return result;
                    }
                }
            }
            result = "127.0.0.1";
            return result;
        }

        public static byte[] ReadSpecifiedLengthFromStream(Stream stream, int length)
        {
            byte[] array = new byte[length];
            int i = 0;
            while (i < length)
            {
                int num = stream.Read(array, i, array.Length - i);
                i += num;
                bool flag = num == 0;
                if (flag)
                {
                    break;
                }
            }
            return array;
        }

        public static void WriteStringToStream(Stream stream, string value)
        {
            byte[] value2 = string.IsNullOrEmpty(value) ? new byte[0] : Encoding.UTF8.GetBytes(value);
            HslHelper.WriteBinaryToStream(stream, value2);
        }

        public static string ReadStringFromStream(Stream stream)
        {
            byte[] bytes = HslHelper.ReadBinaryFromStream(stream);
            return Encoding.UTF8.GetString(bytes);
        }

        public static void WriteBinaryToStream(Stream stream, byte[] value)
        {
            stream.Write(BitConverter.GetBytes(value.Length), 0, 4);
            stream.Write(value, 0, value.Length);
        }

        public static byte[] ReadBinaryFromStream(Stream stream)
        {
            byte[] value = HslHelper.ReadSpecifiedLengthFromStream(stream, 4);
            int num = BitConverter.ToInt32(value, 0);
            bool flag = num <= 0;
            byte[] result;
            if (flag)
            {
                result = new byte[0];
            }
            else
            {
                result = HslHelper.ReadSpecifiedLengthFromStream(stream, num);
            }
            return result;
        }

        public static byte[] GetUTF8Bytes(string message)
        {
            return string.IsNullOrEmpty(message) ? new byte[0] : Encoding.UTF8.GetBytes(message);
        }

        public static string PathCombine(params string[] paths)
        {
            return Path.Combine(paths);
        }

        public static OperateResult<T> ByteArrayToStruct<T>(byte[] content) where T : struct
        {
            OperateResult<T> result;
            int num = Marshal.SizeOf(typeof(T));
            IntPtr intPtr = Marshal.AllocHGlobal(num);
            try
            {
                Marshal.Copy(content, 0, intPtr, num);
                T value = (T)Marshal.PtrToStructure(intPtr, typeof(T));
                Marshal.FreeHGlobal(intPtr);
                result = OperateResult.CreateSuccessResult<T>(value);
            }
            catch (Exception ex)
            {
                Marshal.FreeHGlobal(intPtr);
                result = new OperateResult<T>(ex.Message);
            }
            return result;
        }

        public static void CalculateStartBitIndexAndLength(int addressStart, ushort length, out int newStart, out ushort byteLength, out int offset)
        {
            byteLength = (ushort)((addressStart + (int)length - 1) / 8 - addressStart / 8 + 1);
            offset = addressStart % 8;
            newStart = addressStart - offset;
        }

        public static int CalculateBitStartIndex(string bit)
        {
            bool flag = bit.Contains("A") || bit.Contains("B") || bit.Contains("C") || bit.Contains("D") || bit.Contains("E") || bit.Contains("F");
            int result;
            if (flag)
            {
                result = Convert.ToInt32(bit, 16);
            }
            else
            {
                result = Convert.ToInt32(bit);
            }
            return result;
        }

        public static T[,] CreateTwoArrayFromOneArray<T>(T[] array, int row, int col)
        {
            T[,] array2 = new T[row, col];
            int num = 0;
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    array2[i, j] = array[num];
                    num++;
                }
            }
            return array2;
        }
    }
}
